﻿using DAL.Interface;
using Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq.Expressions;
using System.Transactions;

namespace DAL
{
    public class BaesRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new()
    {
        private EntityDbContext _dbContext;
        public BaesRepository(EntityDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        /// <summary>
        /// 添加单条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        /// <exception cref="MyCustomException"></exception>
        public int Add(TEntity entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new MyCustomException("实体类为空", 500);
                }
                _dbContext.Set<TEntity>().Add(entity);

                return _dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作失败" + ex.Message, 500);
            }
        }
        /// <summary>
        /// 添加单条数据（异步）
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        /// <exception cref="MyCustomException"></exception>
        public async Task<int> AddAsync(TEntity entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new MyCustomException("实体类为空", 500);
                }
                await _dbContext.Set<TEntity>().AddAsync(entity);
                return await _dbContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作失败" + ex.Message, 500);
            }
        }

        /// <summary>
        /// 批量添加——集合
        /// </summary>
        /// <param name="entityList"></param>
        /// <returns></returns>
        public int AddRange(List<TEntity> entityList)
        {
            try
            {
                if (entityList == null && entityList!.Count() == 0)
                {
                    throw new MyCustomException("实体类为空", 500);
                }
                _dbContext.Set<TEntity>().AddRange(entityList!);
                return _dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作失败" + ex.Message, 500);
            }
        }

        /// <summary>
        /// 批量添加——集合（异步）
        /// </summary>
        /// <param name="entityList"></param>
        /// <returns></returns>
        public async Task<int> AddRangeAsync(List<TEntity> entityList)
        {
            try
            {
                if (entityList == null && entityList!.Count() == 0)
                {
                    throw new MyCustomException("实体类为空", 500);
                }
                await _dbContext.Set<TEntity>().AddRangeAsync(entityList!);
                return await _dbContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作失败" + ex.Message, 500);
            }
        }
        /// <summary>
        /// 带有事务的批量添加——集合（异步）
        /// </summary>
        /// <param name="entityList"></param>
        /// <returns></returns>
        /// <exception cref="MyCustomException"></exception>
        public async Task<int> AddRangeTransactionAsync(List<TEntity> entityList)
        {
            try
            {
                if (entityList == null && entityList!.Count() == 0)
                {
                    throw new MyCustomException("实体类为空", 500);
                }
                await SaveChangesWithTransactionAsync(async () =>
                  {
                      await _dbContext.Set<TEntity>().AddRangeAsync(entityList!);
                  });
                return entityList!.Count;
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作失败" + ex.Message, 500);
            }
        }
        /// <summary>
        /// 提交事务
        /// </summary>
        /// <param name="action"></param>
        /// <exception cref="MyCustomException"></exception>
        public void SaveChangesWithTransaction(Action action)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                    action(); // 执行传入的操作
                    _dbContext.SaveChanges(); // 保存更改
                    scope.Complete(); // 提交事务
                }
                catch (Exception ex)
                {
                    //自动回滚事务
                    // 处理异常（例如记录日志）
                    throw new MyCustomException("事务回滚:" + ex.Message, 500); // 重新抛出异常以供外部捕获
                }
            }
        }
  
        /// <summary>
        /// 提交事务(异步)
        /// </summary>
        /// <param name="asyncAction"></param>
        /// <returns></returns>
        /// <exception cref="MyCustomException"></exception>
        public async Task SaveChangesWithTransactionAsync(Func<Task> asyncAction)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required,
                   TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    await asyncAction(); // 执行传入的异步操作
                    await _dbContext.SaveChangesAsync(); // 异步保存更改
                    scope.Complete(); // 提交事务
                }
                catch (Exception ex)
                {
                    // 自动回滚事务(不需要显式操作，Dispose时会自动回滚)
                    // 处理异常（例如记录日志）
                    throw new MyCustomException("事务回滚:" + ex.Message, 500); // 重新抛出异常以供外部捕获
                }
            }
        }
        /// <summary>
        /// 根据条件返回一行数据
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public TEntity? FirstOrDefault(Expression<Func<TEntity, bool>> action)
        {
            try
            {
                return _dbContext.Set<TEntity>().FirstOrDefault(action);
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作出错" + ex.Message, 500);
            }
        }

        public Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> action)
        {
            try
            {
                return _dbContext.Set<TEntity>().FirstOrDefaultAsync(action)!;
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作出错" + ex.Message, 500);
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(TEntity entity)
        {
            try
            {
                _dbContext.Update(entity);
                return _dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作出错" + ex.Message, 500);
            }
        }
        /// <summary>
        /// 修改（异步）
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int UpdateRange(TEntity entity)
        {
            try
            {
                _dbContext.UpdateRange(entity);
                return _dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作出错" + ex.Message, 500);
            }
        }

  

        public IQueryable Queryable(Expression<Func<TEntity, bool>> action)
        {
            try
            {
                return _dbContext.Set<TEntity>().Where(action)!;
            }
            catch (Exception ex)
            {
                throw new MyCustomException("操作出错" + ex.Message, 500);
            }
        }

        public List<TEntity> GetList(Expression<Func<TEntity, bool>>? predicate = null)
        {
            try
            {
                var query = _dbContext.Set<TEntity>().AsQueryable();

                if (predicate != null)
                {
                    query = query.Where(predicate);
                }

                return query.ToList();
            }
            catch (Exception ex)
            {
                throw new MyCustomException($"获取列表失败: {ex.Message}", 500, ex);
            }
        }

        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>>? predicate = null,
                                                   CancellationToken cancellationToken = default)
        {
            try
            {
                var query = _dbContext.Set<TEntity>().AsQueryable();

                if (predicate != null)
                {
                    query = query.Where(predicate);
                }

                return await query.ToListAsync(cancellationToken);
            }
            catch (Exception ex)
            {
                throw new MyCustomException($"获取列表失败: {ex.Message}", 500, ex);
            }
        }
    }
}
